﻿using Dapper;
using ProTrack.Dto;
using ProTrack.Entity;
using ProTrack.IRepository;
using ProTrack.IRepository.WareHouse;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProTrack.Repository.WareHouse
{
    /// <summary>
    /// 生产退料
    /// </summary>
    public class OrderProductReceiveRepository : IOrderProductReceiveRepository
    {
        public OrderProductReceiveRepository(IBaseConnection baseConnection, IStockRepository stock)
        {
            BaseConnection = baseConnection.GetConn();
            StockDb = stock;
        }

        public SqlConnection BaseConnection { get; }
        public IStockRepository StockDb { get; }

        public async Task<bool> AddOrderProductReceive(OrderProductReceive model, List<OrderProductReceiveItem> list)
        {
            if (BaseConnection.State != ConnectionState.Open)
            {
                BaseConnection.Open();
            }
            using (IDbTransaction tran = BaseConnection.BeginTransaction())
            {
                try
                {

                    // 主表 模型
                    var type = model.GetType();

                    var Field = string.Join(',', type.GetProperties().Select(p => p.Name));
                    var Values = string.Join(',', type.GetProperties().Select(p => "@" + p.Name));
                    //剔除Id 
                    Field = Field.Substring(Field.IndexOf("Id,") + 3);
                    Values = Values.Substring(Values.IndexOf($"@Id,") + 4);
                    string Sql = "";
                    if (model.OrderProductPickId!=null)
                    {
                        Sql += $" update OrderProductPick set Status=2 where Id={model.OrderProductPickId}";
                    }

                    Sql += $" Insert into {type.Name}({Field}) values ({Values});Select @@Identity;";

                    //插入主表，获取自增列Id
                    var Id = await BaseConnection.ExecuteScalarAsync(Sql, model, tran);




                    //从表集合处理
                    if (list.Count() > 0)
                    {
                        var t_type = list.FirstOrDefault().GetType();


                        var t_Field = string.Join(',', t_type.GetProperties().Select(p => p.Name));
                        var t_Values = string.Join(',', t_type.GetProperties().Select(p => "@" + p.Name));

                        //剔除Id 
                        t_Field = t_Field.Substring(t_Field.IndexOf("Id,") + 3);
                        t_Values = t_Values.Substring(t_Values.IndexOf($"@Id,") + 4);

                        string TModelSql = $"Insert into {t_type.Name}({t_Field}) values ({t_Values})";


                        string InnerFieldName = type.Name + "Id";

                        //处理关联数据，将从表关联字段的值 设置成主表的值
                        foreach (var item in list)
                        {
                            var types = item.GetType();


                            //找到当前从表所关联主表的字段 并赋值
                            var props = types.GetProperties().FirstOrDefault(x => x.Name.Equals(InnerFieldName));
                            if (props != null)
                            {
                                props.SetValue(item, Convert.ToInt64(Id));
                            }
                        }

                        //Insert To Model
                        await BaseConnection.ExecuteAsync(TModelSql, list, tran);
                    }



                    //操作库存
                    var clist = list.Select(x =>
                    {
                        return new ItemStockDto
                        {
                            Count = (int)x.Count,
                            ItemId = x.ItemId,
                            WareHouseId = model.WarehouseId
                        };
                    }).ToList();

                    await StockDb.AddStock(clist, BaseConnection, tran);



                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    //此处应当日志记录
                    tran.Rollback();
                    throw ex;
                }
            }
        }

        public async Task<bool> Delete(int[] Ids)
        {
            if (BaseConnection.State != ConnectionState.Open)
            {
                BaseConnection.Open();
            }
            using (IDbTransaction tran = BaseConnection.BeginTransaction())
            {
                try
                {
                     


                    var clist = await BaseConnection.QueryAsync<ItemStockDto>(@"select ord.Count,ord.ItemId,o.WarehouseId  from OrderProductReceiveItem ord 
                            inner join OrderProductReceive o on o.Id=ord.OrderProductReceiveId 
					        where ord.OrderProductReceiveId in @Ids", new { Ids }, tran);
                    //减少如库数量 还原商品
                    await StockDb.SubStock(clist.ToList(), BaseConnection, tran);


                    //修改生产领料 订单状态
                    await BaseConnection.ExecuteAsync($"update OrderProductPick set Status=1 where Id in (select OrderProductPickId from OrderProductReceive where Id in @Ids)", new { Ids }, tran);

                    //删除当前订单子项
                    await BaseConnection.ExecuteAsync("delete OrderProductReceiveItem where OrderProductReceiveId in @Ids delete OrderProductReceive where Id in @Ids", new { Ids }, tran);

                    tran.Commit();
                    return true;

                }
                catch (Exception ex)
                {
                    //此处应当日志记录
                    tran.Rollback();
                    throw ex;
                }

            }
        }

        public async Task<bool> Delete(int Id)
        {
            if (BaseConnection.State != ConnectionState.Open)
            {
                BaseConnection.Open();
            }
            using (IDbTransaction tran = BaseConnection.BeginTransaction())
            {
                try
                {

                    var clist = await BaseConnection.QueryAsync<ItemStockDto>(@"select ord.Count,ord.ItemId,o.WarehouseId  from OrderProductReceiveItem ord 
                            inner join OrderProductReceive o on o.Id=ord.OrderProductReceiveId 
					        where ord.OrderProductReceiveId = @Id", new { Id }, tran);
                    //减少如库数量 还原商品
                    await StockDb.SubStock(clist.ToList(), BaseConnection, tran);



                    //修改生产领料 订单状态
                    await BaseConnection.ExecuteAsync($"update OrderProductPick set Status=1 where Id = (select OrderProductPickId from OrderProductReceive where Id = @Id)", new { Id }, tran);



                    //删除当前订单子项
                    await BaseConnection.ExecuteAsync("delete OrderProductReceiveItem where OrderProductReceiveId=@Id delete OrderProductReceive where Id=@Id", new { Id }, tran);

                    tran.Commit();
                    return true;

                }
                catch (Exception ex)
                {
                    //此处应当日志记录
                    tran.Rollback();
                    throw ex;
                }

            }


           
        }

        public async Task<bool> UpdateOrderProductReceive(OrderProductReceive model, List<OrderProductReceiveItem> list)
        {
            if (BaseConnection.State != ConnectionState.Open)
            {
                BaseConnection.Open();
            }
            using (IDbTransaction tran = BaseConnection.BeginTransaction())
            {
                try
                {

                    //获取修改前的订单子项，将库存还原
                    var oldItemList = await BaseConnection.QueryAsync<OrderProductReceiveItem>("select * from OrderProductReceiveItem where OrderProductReceiveId=@Id", new { model.Id }, tran);
                    


                    //删除当前订单子项
                    await BaseConnection.ExecuteAsync("delete OrderProductReceiveItem where OrderProductReceiveId=@Id", new { model.Id }, tran);





                    //主表 Model
                    var type = model.GetType();
                    var modelName = type.Name;

                    var Field = string.Join(',', type.GetProperties().Select(p => $"{p.Name}=@{p.Name}"));
                    //剔除Id
                    Field = Field.Replace("Id=@Id,", "");
                    string Sql = $"update {type.Name} set {Field}  where Id=@Id";

                    //Update To Model 
                    //更新Model
                    await BaseConnection.ExecuteAsync(Sql, model, tran);




                    //从表集合处理
                    if (list.Count() > 0)
                    {
                        var t_type = list.FirstOrDefault().GetType();


                        var t_Field = string.Join(',', t_type.GetProperties().Select(p => p.Name));
                        var t_Values = string.Join(',', t_type.GetProperties().Select(p => "@" + p.Name));

                        //剔除Id 
                        t_Field = t_Field.Substring(t_Field.IndexOf("Id,") + 3);
                        t_Values = t_Values.Substring(t_Values.IndexOf($"@Id,") + 4);

                        string TModelSql = $"Insert into {t_type.Name}({t_Field}) values ({t_Values})";


                        string InnerFieldName = type.Name + "Id";

                        //处理关联数据，将从表关联字段的值 设置成主表的值
                        foreach (var item in list)
                        {
                            var types = item.GetType();


                            //找到当前从表所关联主表的字段 并赋值
                            var props = types.GetProperties().FirstOrDefault(x => x.Name.Equals(InnerFieldName));
                            if (props != null)
                            {
                                props.SetValue(item, Convert.ToInt64(model.Id));
                            }
                        }

                        //Insert To Model
                        await BaseConnection.ExecuteAsync(TModelSql, list, tran);
                    }



                    //操作库存
                    {
                        var clist = list.Select(x =>
                        {
                            return new ItemStockDto
                            {
                                Count = (int)x.Count,
                                ItemId = x.ItemId,
                                WareHouseId = model.WarehouseId
                            };
                        }).ToList();

                        await StockDb.AddStock(clist, BaseConnection, tran);
                    }


                    //增加库存 还原商品
                    {
                        var clist = oldItemList.Select(x =>
                        {
                            return new ItemStockDto
                            {
                                Count = (int)x.Count,
                                ItemId = x.ItemId,
                                WareHouseId = model.WarehouseId
                            };
                        }).ToList();

                        await StockDb.SubStock(clist, BaseConnection, tran);
                    }


                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    //此处应当日志记录
                    tran.Rollback();
                    throw ex;
                }
            }
        }
    }
}
